// eslint-disable-next-line import/no-extraneous-dependencies
import { Request, Response } from 'express';
import { parse } from 'url';
import {
  ProjectListItem,
  ProjectListParams,
  ProjectBlueprintList,
  BlueprintItem,
  ProjectBlueprintQueryParams,
} from '@/pages/ProjectList/data';
import { findIndex, toNumber } from 'lodash';

const DEFAULT_BLUEPRINT_DATA = [
  { key: 'major1', title: '建筑', subItem: [] },
  { key: 'major2', title: '结构', subItem: [] },
  { key: 'major3', title: '给排水', subItem: [] },
  { key: 'major4', title: '暖通', subItem: [] },
  { key: 'major5', title: '电气', subItem: [] },
];

// mock projectListDataSource
let projectListDataSource: ProjectListItem[] = [];
let projectBlueprintDataSource: ProjectBlueprintList[] = [];

function getProjectById(req: Request, res: Response) {
  const {
    params: { id },
  } = req;
  const index = findIndex(projectListDataSource, (val) => val.key === toNumber(id));
  if (index < 0) {
    return res.json({});
  }
  return res.json(projectListDataSource[index]);
}

function getProject(req: Request, res: Response, u: string) {
  let realUrl = u;
  if (!realUrl || Object.prototype.toString.call(realUrl) !== '[object String]') {
    realUrl = req.url;
  }
  const { current = 1, pageSize = 10 } = req.query;
  const params = (parse(realUrl, true).query as unknown) as ProjectListParams;

  let dataSource = [...projectListDataSource].slice(
    ((current as number) - 1) * (pageSize as number),
    (current as number) * (pageSize as number),
  );
  const sorter = JSON.parse(params.sorter as any);
  if (sorter) {
    dataSource = dataSource.sort((prev, next) => {
      let sortNumber = 0;
      Object.keys(sorter).forEach((key) => {
        if (sorter[key] === 'descend') {
          if (prev[key] - next[key] > 0) {
            sortNumber += -1;
          } else {
            sortNumber += 1;
          }
          return;
        }
        if (prev[key] - next[key] > 0) {
          sortNumber += 1;
        } else {
          sortNumber += -1;
        }
      });
      return sortNumber;
    });
  }
  if (params.filter) {
    const filter = JSON.parse(params.filter as any) as {
      [key: string]: string[];
    };
    if (Object.keys(filter).length > 0) {
      dataSource = dataSource.filter((item) => {
        return Object.keys(filter).some((key) => {
          if (!filter[key]) {
            return true;
          }
          if (filter[key].includes(`${item[key]}`)) {
            return true;
          }
          return false;
        });
      });
    }
  }

  if (params.name) {
    dataSource = dataSource.filter((data) => data.name.includes(params.name || ''));
  }
  const result = {
    data: dataSource,
    total: projectListDataSource.length,
    success: true,
    pageSize,
    current: parseInt(`${params.currentPage}`, 10) || 1,
  };

  return res.json(result);
}

function postProject(req: Request, res: Response, u: string, b: Request) {
  let realUrl = u;
  if (!realUrl || Object.prototype.toString.call(realUrl) !== '[object String]') {
    realUrl = req.url;
  }

  const body = (b && b.body) || req.body;
  const { method, name, desc, key } = body;

  switch (method) {
    /* eslint no-case-declarations:0 */
    case 'delete':
      projectListDataSource = projectListDataSource.filter((item) => key.indexOf(item.key) === -1);
      projectBlueprintDataSource = projectBlueprintDataSource.filter(
        (item) => key.indexOf(item.key) === -1,
      );
      break;
    case 'post':
      (() => {
        const i = Math.ceil(Math.random() * 10000);
        const newKey = projectListDataSource.length;
        const newProject = {
          key: newKey,
          href: 'https://ant.design',
          avatar: [
            'https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png',
            'https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png',
          ][i % 2],
          name,
          owner: '曲丽丽',
          desc,
          jianzhu: 0,
          jiegou: 0,
          jipaishui: 0,
          nuantong: 0,
          dianqi: 0,
          updatedAt: new Date(),
          createdAt: new Date(),
          progress: Math.ceil(Math.random() * 100),
        };
        projectListDataSource.unshift(newProject);
        const newBluepringData: ProjectBlueprintList = {
          key: newKey,
          list: DEFAULT_BLUEPRINT_DATA,
        };
        projectBlueprintDataSource.unshift(newBluepringData);
        return res.json({ newProject, projectBlueprintDataSource });
      })();
      return;

    case 'update':
      (() => {
        let newProject = {};
        projectListDataSource = projectListDataSource.map((item) => {
          if (item.key === key) {
            newProject = { ...item, desc, name };
            return { ...item, desc, name };
          }
          return item;
        });
        return res.json(newProject);
      })();
      return;
    default:
      break;
  }

  const result = {
    list: projectListDataSource,
    pagination: {
      total: projectListDataSource.length,
    },
  };

  res.json(result);
}

function getBlueprint(req: Request, res: Response, u: string) {
  let realUrl = u;
  if (!realUrl || Object.prototype.toString.call(realUrl) !== '[object String]') {
    realUrl = req.url;
  }
  const params = (parse(realUrl, true).query as unknown) as ProjectBlueprintQueryParams;
  if (params.projectKey) {
    const i1 = findIndex(projectBlueprintDataSource, (p) => p.key === toNumber(params.projectKey));
    if (i1 < 0) {
      return res.json([]);
    }
    const pB = projectBlueprintDataSource[i1].list || [];
    if (params.majorKey) {
      const i2 = findIndex(pB, (b: BlueprintItem) => b.key === params.majorKey);
      if (i2 < 0) {
        return res.json([]);
      }
      const mB = pB[i2].subItem || [];
      if (params.unitKey) {
        const i3 = findIndex(mB, (b: BlueprintItem) => b.key === params.unitKey);
        if (i3 < 0) {
          return res.json([]);
        }
        const uB = mB[i3].subItem || [];
        if (params.blueprintKey) {
          return res.json(uB.filter((b) => b.key === params.blueprintKey));
        }
        return res.json(uB);
      }
      return res.json(mB);
    }
    return res.json(pB);
  }
  return res.json([]);
}

function postBlueprint(req: Request, res: Response, u: string, b: Request) {
  let realUrl = u;
  if (!realUrl || Object.prototype.toString.call(realUrl) !== '[object String]') {
    realUrl = req.url;
  }

  const body = (b && b.body) || req.body;
  const { method, projectKey, majorKey, unitKey, blueprintKey, blueprintItem } = body;
  switch (method) {
    case 'delete':
      projectBlueprintDataSource = projectBlueprintDataSource.map(
        (project: ProjectBlueprintList) => {
          if (project.key === projectKey) {
            return {
              ...project,
              list: project.list.map((major: BlueprintItem) => {
                if (major.key === majorKey) {
                  return {
                    ...major,
                    subItem:
                      major.subItem &&
                      major.subItem.map((unit: BlueprintItem) => {
                        if (unit.key === unitKey) {
                          return {
                            ...unit,
                            subItem:
                              unit.subItem &&
                              unit.subItem.filter((graph) => graph.key !== blueprintKey),
                          };
                        }
                        return unit;
                      }),
                  };
                }
                return major;
              }),
            };
          }
          return project;
        },
      );
      break;
    case 'post':
      (() => {
        projectBlueprintDataSource = projectBlueprintDataSource.map(
          (project: ProjectBlueprintList) => {
            if (project.key === projectKey) {
              return {
                ...project,
                list: blueprintItem,
              };
            }
            return project;
          },
        );
      })();
      return res.json({ success: true, data: blueprintItem });
    default:
      break;
  }
  return res.json({ success: true });
}

function addUnit(req: Request, res: Response, u: string, b: Request) {
  let realUrl = u;
  if (!realUrl || Object.prototype.toString.call(realUrl) !== '[object String]') {
    realUrl = req.url;
  }

  const body = (b && b.body) || req.body;
  const { projectKey, majorKey, blueprintItem } = body;
  projectBlueprintDataSource = projectBlueprintDataSource.map((project) => {
    if (project.key === projectKey) {
      return {
        ...project,
        list: project.list.map((major) => {
          if (major.key === majorKey) {
            const newSubItem = major.subItem?.concat(blueprintItem);
            return {
              ...major,
              subItem: newSubItem,
            };
          }
          return major;
        }),
      };
    }
    return project;
  });
  return res.json({ success: true });
}

function addGraph(req: Request, res: Response, u: string, b: Request) {
  let realUrl = u;
  if (!realUrl || Object.prototype.toString.call(realUrl) !== '[object String]') {
    realUrl = req.url;
  }

  const body = (b && b.body) || req.body;
  const { projectKey, majorKey, unitKey, blueprintItem } = body;
  projectBlueprintDataSource = projectBlueprintDataSource.map((project) => {
    if (project.key === projectKey) {
      return {
        ...project,
        list: project.list.map((major) => {
          if (major.key === majorKey) {
            return {
              ...major,
              subItem: major.subItem?.map((unit) => {
                if (unit.key === unitKey) {
                  const newSubItem = unit.subItem?.concat(blueprintItem);
                  return {
                    ...unit,
                    subItem: newSubItem,
                  };
                }
                return unit;
              }),
            };
          }
          return major;
        }),
      };
    }
    return project;
  });
  return res.json({ success: true });
}

export default {
  'GET /api/project': getProject,
  'GET /api/project/:id': getProjectById,
  'POST /api/project': postProject,
  'GET /api/blueprint': getBlueprint,
  'POST /api/blueprint': postBlueprint,
  'POST /api/blueprint/addUnit': addUnit,
  'POST /api/blueprint/addGraph': addGraph,
};
